home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / vol_400 / 405_01 / Discussion / partx-sun-attachment0 < prev   
Encoding:
Text File  |  1993-07-17  |  8.2 KB  |  314 lines

  1. ----------
  2. X-Sun-Data-Type: text
  3. X-Sun-Data-Description: text
  4. X-Sun-Data-Name: text
  5. X-Sun-Content-Lines: 114
  6.  
  7.  
  8. > From root Thu Jul 15 20:00:27 1993
  9. > >From ramanand@thor.ece.uc.EDU Thu Jul 15 20:00:27 1993
  10. > Date: 15 Jul 93 13:57:27-0400
  11. > From: John Holmes Sr <ramanand@thor.ece.uc.EDU>
  12. > Subject: flex++/bison++
  13. > To: coetmeur@icdc.fr
  14. > MIME-version: 1.0
  15. > Content-Type> : > text/plain> ; > charset=US-ASCII> 
  16. > Content-transfer-encoding: 7bit
  17. > Hello Alain,
  18. > I recently ported the flex++/bison++ software that you have put up on the
  19. > ftp server under comp.compilers. 
  20. > First of all I would like to complement you on a job well underakten. The
  21. > documentation is quite beneficial. 
  22. > However I have been having some problems with generating multiple parsers
  23. > in the same executable. It is quite possible that my understanding of the
  24. > full capabilities of the notions of class etc. are not quite up to the
  25. > mark. I would appreciate any help you can provide.
  26. > I have tried the following approach. If there is a better way, please let
  27. > me know.
  28. >     Prepare two bison++ files. Each of them declares a different class
  29. >     for the parser. Each of them declares its LEX_BODY as = 0 (i.e. a
  30. >     pure virtual function). Prepare two flex++ files. Each of them
  31. >     inherits the properties of the corresponding parser class and defines
  32. >     the lexical analyser functions. 
  33. >     So I now have two sets of header files. 
  34. >         a. parser1.h and lex1.h
  35. >         b. parser2.h and lex2.h
  36. >     
  37. > Each set of parser/lexical analyser individually compiles correctly
  38. > with the latest gnu c++  compiler. However, if I try to include both
  39. > the lexical header files (lex1.c and lex2.c) in the main file, I get syntax
  40. > errors. The reason is in the first two lines of these header files. They
  41. > are duplicated here below:
  42. >     #ifndef FLEX_HEADER_lex__h
  43. >     #define FLEX_HEADER_lex__h
  44. >     ...
  45. >     ...
  46. > Since both these files define the same symbol FLEX_HEADER_lex__h,
  47. > obviously the second time that I include the header file, it is ignored
  48. > by the preprocessor. 
  49. > Can you give me some solutions to this. Either I could somehow rename this
  50. > symbol , or you have  a better class hierarchy that I am unaware of
  51. > currently. 
  52.  
  53.  
  54.  
  55.     The way we can use multiple parser or scanner is by changing
  56.    the name of the scanner/parser with the directive %name. it is
  57.    ESSENTIAL. By default and for compatibility the name is set to 'lex'
  58.    and 'parse', but it should be changed to a different name for each
  59.    parser/scanner. Further, the scanner and parser must not have the
  60.    same name. the name given is used as the class name, and to build
  61.    many symbol names. So you should give a %name directive, before any
  62.    other in the flex++ and bison++ files. If all the header use the
  63.    symbol FLEX_HEADER_lex__h if shoul mean that they use the same
  64.    %name. If it is not the case, it is a very important bug. I was not
  65.    able to reproduce it with the data I have.
  66.  
  67.     The way to comunicate between the scanner and the parser is not
  68.    a trivial choic, and at our site we discussed much about it. The
  69.    problems are complex since the scanner use parser constant for token
  70.    ID, the parser use the scanner function as token furnisher, and so
  71.    on...
  72.  
  73.     The way that we used is to create a derived class from the
  74.    parser class, containing the scanner itself, and redefining the
  75.    token reader function of the parser to call the scanner function of
  76.    the scanner. It seems good for many reasons:
  77.  
  78.        - the compiler (ie parser+scanner) IS essentially a PARSER,
  79.          that USE a particular SCANNER to give tokens.
  80.  
  81.        - the intermediate function that give tokens from the
  82.          scanner to the parser is a good place to put trace, and
  83.          management function (line count...)
  84.  
  85.      The design was so important to explain to new users in our
  86.     site, that I decided to build a template of compiler that is a
  87.     base to modify. It should be present in misc++, but I send it as
  88.     attachment (4 files).
  89.  
  90.     I am concient that the documentation I have given is very
  91.     technical, and assume a deep knowledge of flex, bison, C/C++, and
  92.     some design experiences.
  93.  
  94.  
  95.     Please tell me was is the result of your new try, successful or not.
  96.  
  97.     Hoping I could help you, Best regard.
  98.  
  99.  
  100.     Alain Coetmeur
  101.  
  102.  
  103. ----------
  104. X-Sun-Data-Type: rdti-source-makefile
  105. X-Sun-Data-Name: makefile
  106. X-Sun-Content-Lines: 28
  107.  
  108.  
  109.  
  110. .SUFFIXES : .cc .y .l $(SUFFIXES)
  111.  
  112. .cc.o :
  113.     CC   -I$(CENTERCCLIBDIR)/incl -c  $*.cc
  114.  
  115. .y.cc :
  116.     bison++ -d  -o $*.cc -h $*.h  $*.y
  117. .l.cc :
  118.     flex++    -h$*.h -o$*.cc $*.l
  119. .y.h :
  120.     bison++ -d  -o $*.cc -h $*.h  $*.y
  121. .l.h :
  122.     flex++    -h$*.h -o$*.cc $*.l
  123.  
  124. all : compiler
  125.  
  126. MyCompiler.o : MyCompiler.cc MyParser.h MyScanner.h
  127.  
  128. MyParser.o : MyParser.cc MyParser.h
  129.  
  130. MyScanner.o : MyScanner.cc MyScanner.h MyParser.h
  131.  
  132.  
  133. compiler : MyCompiler.o MyParser.o MyScanner.o
  134.     CC  -o $@ MyCompiler.o MyParser.o MyScanner.o
  135.  
  136. ----------
  137. X-Sun-Data-Type: rdtq-source-l
  138. X-Sun-Data-Name: MyScanner.l
  139. X-Sun-Content-Lines: 42
  140.  
  141. /* %Z% %M% %Y% %Q% %I% %E% %U% (%F%) */
  142. /*
  143.  * Nom du Fichier :     |>nom_fichier<|
  144.  * Titre :         |>Titre<|
  145.  * Auteur:        |>auteur<|        
  146.  * Date de creation :    |>dateCreation<|
  147.  */
  148. /* Description :
  149.  *    Document de reference : |>doc<|
  150.  *    Objet : |>objet<|
  151.  *
  152.  */
  153. /* 
  154.  * historique :
  155.  * |>date<|    |>auteur<|    |>objet<|
  156.  */
  157. /* -------------- declaration section -------------- */
  158. %name MyScanner
  159.  
  160. %define LEX_PARAM YY_MyParser_STYPE *val,YY_MyParser_LTYPE *loc
  161. %define MEMBERS public: int theLine,theColumn;
  162. %define CONSTRUCTOR_INIT : theLine(1),theColumn(1)
  163. %header{ 
  164. #include "MyParser.h"
  165. %}
  166.  
  167. %{
  168. static char SccsId[]="%Z% %M% %Y% %Q% %I% %E% %U% (%F%)";
  169. %}
  170.  
  171. /* -------------- rules section -------------- */
  172. SPACES [ \t]+
  173. %%
  174. "\n"    {val->ctype='\n';
  175.          theLine++;theColumn=1;
  176.          return MyParser::EOL_TOKEN; }
  177. .    {
  178.          val->ctype=yytext[0];
  179.          theColumn++;
  180.          return MyParser::CHAR_TOKEN; }
  181. <<EOF>> { yyterminate();}
  182. %%
  183. ----------
  184. X-Sun-Data-Type: rdtq-source-y
  185. X-Sun-Data-Name: MyParser.y
  186. X-Sun-Content-Lines: 50
  187.  
  188. /* %Z% %M% %Y% %Q% %I% %E% %U% (%F%) */
  189. /*
  190.  * Nom du Fichier :     |>nom_fichier<|
  191.  * Titre :         |>Titre<|
  192.  * Auteur:        |>auteur<|
  193.  * Date de creation :    |>dateCreation<|
  194.  */
  195. /* Description :
  196.  *    Document de reference : |>doc<|
  197.  *    Objet : |>objet<|
  198.  *
  199.  */
  200. /*
  201.  * historique :
  202.  * |>date<|    |>auteur<|    |>objet<|
  203.  */
  204. /* -------------- declaration section -------------- */
  205.  
  206. %name MyParser
  207. %define LSP_NEEDED
  208. %define ERROR_BODY =0
  209. %define LEX_BODY =0
  210. %header{
  211. #include <stdio.h>
  212. %}
  213.  
  214. %union {
  215.     int itype;    /* for count */
  216.     char ctype;    /* for char */
  217.     }
  218. %token <ctype> EOL_TOKEN CHAR_TOKEN
  219. %type <itype> file line lines chars
  220. %start file
  221.  
  222. /* -------------- rules section -------------- */
  223. /* Sample parser. Does count Chars in a line, and lines in file */
  224. %%
  225. file    : lines
  226.     {printf("nlines=%d\n",$1); /* show line count */}
  227.     ;
  228. lines     : line {$$=1; /* first line of all */}
  229.     | lines line {$$=$1+1;    /* count one more line */}
  230.     ;
  231. line     : chars EOL_TOKEN {$$=$1;printf("nchars=%d\n",$1); /* show char count */}
  232.     ;
  233. chars    : CHAR_TOKEN { $$=1;/* first char of line */}
  234.     | chars CHAR_TOKEN {$$=$1+1; /* count one more char */}
  235.     ;
  236. %%
  237. /* -------------- body section -------------- */
  238. ----------
  239. X-Sun-Data-Type: rdtq-source-cc
  240. X-Sun-Data-Name: MyCompiler.cc
  241. X-Sun-Content-Lines: 52
  242.  
  243. static char SccsId[]="%Z% %M% %Y% %Q% %I% %E% %U% (%F%)";
  244. //
  245. // Nom du Fichier :     |>nom_fichier<|
  246. // Titre :         |>Titre<|
  247. // Auteur:        |>auteur<|        
  248. // Date de creation :    |>dateCreation<|
  249. //
  250. // Description :
  251. //    Document de reference : |>doc<|
  252. //    Objet : |>objet<|
  253. //
  254. //
  255. // 
  256. // historique :
  257. // |>date<|    |>auteur<|    |>objet<|
  258. //
  259. #include "MyScanner.h"
  260. #include "MyParser.h"
  261.  
  262. class MyCompiler : public MyParser
  263. {private:
  264.  MyScanner theScanner;
  265.  public:
  266.  virtual int yylex();
  267.  virtual void yyerror(char *m);
  268.  MyCompiler() 
  269.   {};
  270. };
  271.  
  272. int MyCompiler::yylex()
  273. {
  274.  yylloc.first_line=theScanner.theLine;
  275.  yylloc.first_column=theScanner.theColumn;
  276.  int token=theScanner.yylex(&yylval,&yylloc);
  277.  yylloc.last_line=theScanner.theLine;
  278.  yylloc.last_column=theScanner.theColumn;
  279.  yylloc.text=(char *)theScanner.yytext;
  280.  return token;
  281. }
  282.  
  283. void MyCompiler::yyerror(char *m)
  284. { fprintf(stderr,"%d: %s at token '%s'\n",yylloc.first_line, m,yylloc.text);
  285. }
  286.  
  287. int main(int argc,char **argv)
  288. {
  289.  MyCompiler aCompiler;
  290.  int result=aCompiler.yyparse();
  291.  printf("Resultat Parsing=%s\n",result?"Erreur":"OK");
  292.  return 0;
  293. };
  294.  
  295.  
  296.